package com.reservation.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reservation.common.Result;
import com.reservation.entity.GuideReservation;
import com.reservation.service.GuideReservationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;

/**
 * 解说员预约控制器
 */
@RestController
@RequestMapping("/guide-reservation")
public class GuideReservationController {

    @Autowired
    private GuideReservationService guideReservationService;

    /**
     * 创建解说员预约
     *
     * @param reservation 预约信息
     * @return 创建结果
     */
    @PostMapping
    public Result<GuideReservation> createReservation(@RequestBody @Valid GuideReservation reservation) {
        GuideReservation createdReservation = guideReservationService.createReservation(reservation);
        return Result.success(createdReservation, "预约成功，等待审核");
    }

    /**
     * 更新预约状态（仅管理员可用）
     *
     * @param id     预约ID
     * @param status 预约状态
     * @return 更新结果
     */
    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<GuideReservation> updateReservationStatus(
            @PathVariable Long id,
            @RequestParam String status) {
        GuideReservation reservation = guideReservationService.updateReservationStatus(id, status);
        return Result.success(reservation, "状态更新成功");
    }

    /**
     * 获取预约详情
     *
     * @param id 预约ID
     * @return 预约信息
     */
    @GetMapping("/{id}")
    public Result<GuideReservation> getReservationById(@PathVariable Long id) {
        GuideReservation reservation = guideReservationService.getReservationById(id);
        return Result.success(reservation);
    }

    /**
     * 取消预约
     *
     * @param id 预约ID
     * @return 取消结果
     */
    @PutMapping("/cancel/{id}")
    public Result<Void> cancelReservation(@PathVariable Long id) {
        boolean result = guideReservationService.cancelReservation(id);
        return Result.success(null, "取消预约成功");
    }

    @PutMapping("/confirm/{id}")
    public Result<Boolean> confirm(@PathVariable Long id) {
        boolean confirm = guideReservationService.confirm(id);
        return Result.success(confirm, "确认成功");
    }

    /**
     * 分页查询用户的预约列表
     *
     * @param pageNum  当前页
     * @param pageSize 每页大小
     * @param userId   用户ID
     * @param status   预约状态（可选）
     * @return 预约列表
     */
    @GetMapping("/user/{userId}")
    public Result<IPage<GuideReservation>> getUserReservations(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @PathVariable Long userId,
            @RequestParam(required = false) String status) {
        Page<GuideReservation> page = new Page<>(pageNum, pageSize);
        IPage<GuideReservation> reservationPage = guideReservationService.getUserReservations(page, userId, status);
        return Result.success(reservationPage);
    }

    /**
     * 分页查询解说员的预约列表（仅管理员可用）
     *
     * @param current 当前页
     * @param size    每页大小
     * @param guideId 解说员ID
     * @param status  预约状态（可选）
     * @param date    预约日期（可选）
     * @return 预约列表
     */
    @GetMapping("/guide/{guideId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<IPage<GuideReservation>> getGuideReservations(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @PathVariable Long guideId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
        Page<GuideReservation> page = new Page<>(current, size);
        IPage<GuideReservation> reservationPage = guideReservationService.getGuideReservations(page, guideId, status, date);
        return Result.success(reservationPage);
    }

    /**
     * 分页查询展览的解说预约列表（仅管理员可用）
     *
     * @param pageNum      当前页
     * @param pageSize     每页大小
     * @param exhibitionId 展览ID
     * @param status       预约状态（可选）
     * @param date         预约日期（可选）
     * @return 预约列表
     */
    @GetMapping("/exhibition/{exhibitionId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<IPage<GuideReservation>> getExhibitionGuideReservations(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @PathVariable Long exhibitionId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
        Page<GuideReservation> page = new Page<>(pageNum, pageSize);
        IPage<GuideReservation> reservationPage = guideReservationService.getExhibitionGuideReservations(page, exhibitionId, status, date);
        return Result.success(reservationPage);
    }

    /**
     * 分页查询所有预约列表（仅管理员可用）
     *
     * @param pageNum  当前页
     * @param pageSize 每页大小
     * @param status   预约状态（可选）
     * @return 预约列表
     */
    @GetMapping("/list")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<IPage<GuideReservation>> getAllReservations(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String status) {
        Page<GuideReservation> page = new Page<>(pageNum, pageSize);
        IPage<GuideReservation> reservationPage = guideReservationService.getAllReservations(page, status);
        return Result.success(reservationPage);
    }

    /**
     * 检查用户在指定日期是否已有解说员预约
     *
     * @param userId   用户ID
     * @param guideId  解说员ID
     * @param date     预约日期
     * @param timeSlot 时间段
     * @return 是否已有预约
     */
    @GetMapping("/check")
    public Result<Boolean> checkUserHasReservation(
            @RequestParam Long userId,
            @RequestParam Long guideId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
            @RequestParam String timeSlot) {
        boolean hasReservation = guideReservationService.checkUserHasReservation(userId, guideId, date, timeSlot);
        return Result.success(hasReservation);
    }

    /**
     * 获取用户的所有解说员预约
     *
     * @param userId 用户ID
     * @return 预约列表
     */
    @GetMapping("/user/{userId}/all")
    public Result<List<GuideReservation>> getUserAllReservations(@PathVariable Long userId) {
        List<GuideReservation> reservations = guideReservationService.getUserAllReservations(userId);
        return Result.success(reservations);
    }

    /**
     * 获取解说员的所有预约（仅管理员可用）
     *
     * @param guideId 解说员ID
     * @return 预约列表
     */
    @GetMapping("/guide/{guideId}/all")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<List<GuideReservation>> getGuideAllReservations(@PathVariable Long guideId) {
        List<GuideReservation> reservations = guideReservationService.getGuideAllReservations(guideId);
        return Result.success(reservations);
    }

    /**
     * 获取展览的所有解说员预约（仅管理员可用）
     *
     * @param exhibitionId 展览ID
     * @return 预约列表
     */
    @GetMapping("/exhibition/{exhibitionId}/all")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<List<GuideReservation>> getExhibitionAllGuideReservations(@PathVariable Long exhibitionId) {
        List<GuideReservation> reservations = guideReservationService.getExhibitionAllGuideReservations(exhibitionId);
        return Result.success(reservations);
    }
}